__version__ = "2.0.1"
__author__ = "ArtLinty"

# MIT License
#
# Copyright (c) 2019 立师兄Linty
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
page 包 构造方法，包含
    WebPage：WebUI 业务 继承的基类
    ApiPage：WebAPI 业务 继承的基类

！！！ 请勿直接使用 _BasePage
"""

from base import BoxDriver, Logger, Yaml, Path, BoxRequest
from base.helper import parse_digit


class _BasePage:
    _logger = None

    def __init__(self, logger=None):
        """
        构造方法
        :param logger:
        """
        self._logger = logger

    def log(self, msg):
        """
        记录日志
        :param msg:
        :return:
        """
        if self._logger and type(self._logger) == Logger:
            self._logger.info(msg)

    def config(self, file):
        """
        config
        :param file:
        :return:
        """
        if file and Path.file_is_exist(file):
            self.log("[system] - [%s] read config file: %s" % (__name__, file))
            return Yaml.get_config_as_dict(file)

    def convert_str_to_decimal(self, digit_str):
        """
        转变 字符串（数字组成的字符串）为数字
        :param digit_str: 数字组成的字符串
            规则：
                接受整型 "123"
                接受负数 "-123"
                接受小数 "-123.88"， "123.88"

        :return:
            如果 digit_str 是字符串 str 格式，就转化
            否则，返回 digit_str
        """
        self.log("[system] - [%s] parse_digit: %s" % (__name__, digit_str))
        if digit_str and isinstance(digit_str, str):
            return parse_digit(digit_str)
        return digit_str


class WebPage(_BasePage):
    """
    测试系统的最基础的页面类，是所有其他页面的基类
    """
    # 变量
    _driver = None

    # 方法
    def __init__(self, driver: BoxDriver, logger=None):
        """
        构造方法
        :param driver: 指定了参数类型，BoxDriver
        :param logger: 制定了
        """
        super(WebPage, self).__init__(logger)
        self._driver = driver
        self.log("[Page] - [%s] page initialized! " % __name__)

    def open(self, url):
        """
        打开页面
        :param url:
        :return:
        """
        self.driver.navigate(url)
        self.driver.maximize_window()
        self.driver.forced_wait(2)
        self.log("[Page] - [%s] page navigate: %s! " % (__name__, url))

    @property
    def current_url(self):
        """
        current url
        :return:
        """
        return self.driver.get_url()

    @property
    def title(self):
        """
        title
        :return:
        """
        return self.driver.get_title()

    @property
    def driver(self):
        """
        current driver
        :return:
        """
        return self._driver


class ApiPage(_BasePage):
    _req = None
    _base_url = None

    def __init__(self, base_url, logger=None):
        super(ApiPage, self).__init__(logger)
        self._base_url = base_url
        self.log("[Api] - [%s] api initialized! " % __name__)

    @property
    def response(self):
        """
        get current response
        :return:
        """
        if self._req and isinstance(self._req, BoxRequest):
            return self._req.response

        return None

    def _parse_http_resp(self):
        """
        分析 http 的响应
        :return: 返回 dict
            status_code
            response_headers
            full_response
            json_dict
        """
        resp = {}
        if self._req and isinstance(self._req, BoxRequest):
            resp["status_code"] = self._req.status_code
            resp["response_headers"] = self._req.response_headers
            resp["full_response"] = self._req.response
            resp["json_dict"] = self._req.json_dict

        return resp

    def _handle_params(self, params: dict):
        """
        处理 HTTP 的参数，如果参数的值 为 None，将会移除参数
        :param params:  dict 类型
        :return:
        """
        if params and isinstance(params, dict):
            keys = params.keys()
            keys_to_remove = []
            for k in keys:
                if params[k] is None:
                    keys_to_remove.append(k)

            for ktr in keys_to_remove:
                params.pop(ktr)
                self.log("[Api] - [%s] params 移除了值为 None 的 key:%r! " % (__name__, ktr))

        return params
